package com.itlong.cloud.controller.sdkV2.elevator;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.AppCallLiftSaveDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudDeviceSDKDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudElevatorSDKGetByDeviceUniqueDTO;
import com.itlong.cloud.POJO.DTO.sdk.RobotNoninductiveGetCallInfoVO;
import com.itlong.cloud.POJO.DTO.sdk.RobotNoninductiveHistoryRecordDTO;
import com.itlong.cloud.POJO.PO.DeviceElevatorInfoPO;
import com.itlong.cloud.POJO.VO.SDKMessageVO;
import com.itlong.cloud.POJO.VO.sdk.RobotNoninductiveDeviceUniqueVO;
import com.itlong.cloud.POJO.VO.sdk.RobotNoninductiveHistoryRecordVO;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.CloudElevarotErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.SDKErrorCodeEnum;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.sdk.ICloudElevatorSDKRobotClient;
import com.itlong.cloud.equip.sdk.ICloudElevatorSDKServerCloudServiceClient;
import com.itlong.cloud.iottp.IIotServerServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppHomeServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 * 机器人无感SDK controller
 * </desc>
 *
 * @createDate 2019/07/164022
 */
@RestController
@RequestMapping("/sdk/cloud/elevator/rn")
public class SDKCloudRobotNoninductiveController {
    private static Logger LOG = LoggerFactory.getLogger(SDKCloudRobotNoninductiveController.class);

    @Autowired
    private ICloudElevatorSDKServerCloudServiceClient iCloudElevatorSDKServerCloudServiceClient;

    @Autowired
    SDKCloudElevatorRTLController sdkCloudElevatorRTLController;

    @Autowired
    IAppDeviceServiceClient iAppDeviceServiceClient;

    @Autowired
    IAppHomeServiceClient iAppHomeServiceClient;

    @Autowired
    RedisService redisService;

    @Autowired
    IIotServerServiceClient iIotServerServiceClient;

    @Autowired
    ICloudElevatorSDKRobotClient iCloudElevatorSDKRobotServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    /**
     * <desc>
     * 根据设备唯一码查询电梯信息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2019/07/17
     */
    @UnAuthAccessRequired
    public Object getElevatorInfo(CloudDeviceSDKDTO dto) throws Exception {
        //初始值为 登录为工程人员登录  获取项目下所有的设备
        Integer robotWhiteListAuthStatus=0;
        Integer robotDeviceAuthStatus=0;
        if (!"1".equals(dto.getRoleId())) {
            Map<String, Object> AuthStatus = iOperateProjectServiceClient.getRobotGoProjectWhitelistAndDeviceAuthStatusByUserId(dto.getProjectId(), dto.getAppId());
            robotWhiteListAuthStatus = Integer.parseInt(AuthStatus.get("robotWhiteListAuthStatus") + "");
            robotDeviceAuthStatus = Integer.parseInt(AuthStatus.get("robotDeviceAuthStatus") + "");
        }
        //情况1 机器人白名单授权为 1是 并且机器人设备授权为 1是
        if ("1".equals(robotWhiteListAuthStatus+"")) {
            if (StringUtils.isEmpty(dto.getRobotId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
        }
        CloudElevatorSDKGetByDeviceUniqueDTO cloudElevatorSDKGetByDeviceUniqueDTO = new CloudElevatorSDKGetByDeviceUniqueDTO();
        cloudElevatorSDKGetByDeviceUniqueDTO.setAppId(dto.getAppId());
        cloudElevatorSDKGetByDeviceUniqueDTO.setAppSecret(dto.getAppSecret());
        cloudElevatorSDKGetByDeviceUniqueDTO.setProjectId(dto.getProjectId());
        cloudElevatorSDKGetByDeviceUniqueDTO.setDeviceUnique(dto.getDeviceUnique());
        cloudElevatorSDKGetByDeviceUniqueDTO.setRobotId(robotWhiteListAuthStatus==0?"":dto.getRobotId());

        cloudElevatorSDKGetByDeviceUniqueDTO.setRobotWhiteListAuthStatus(robotWhiteListAuthStatus);
        cloudElevatorSDKGetByDeviceUniqueDTO.setRobotDeviceAuthStatus(robotDeviceAuthStatus);


        dto.setRobotWhiteListAuthStatus(robotWhiteListAuthStatus);
        dto.setRobotDeviceAuthStatus(robotDeviceAuthStatus);
        dto.setRobotId(robotWhiteListAuthStatus==0?"":dto.getRobotId());
        //设备权限以及机器人权限验证
        int result = sdkCloudElevatorRTLController.checkDeveloperAuth(dto);
        if (result == 1) {
            return new SDKMessageVO(SDKErrorCodeEnum.SDK_SERVER_NO_DEVICE_UNIQUE_ERR.getErrorCode(),dto.getRequestId(),dto.getResponseTimestamp(),"");
        } else if (result == 2 && !dto.getRoleId().equals(OperateSystemSetUpEnum.ENGINNER.getType().toString())) {
            return new SDKMessageVO(CloudElevarotErrorCodeEnum.ROBOT_AUTH_ERROR.getErrorCode(),dto.getRequestId(),dto.getResponseTimestamp(),"");
        }
        LOG.info("======getElevatorInfo根据设备唯一码查询电梯信息======无感======入参================>{}",null==cloudElevatorSDKGetByDeviceUniqueDTO?"":cloudElevatorSDKGetByDeviceUniqueDTO.toString());

        List<RobotNoninductiveDeviceUniqueVO> cloudElevatorSDKGetByDeviceUniqueVOS = iCloudElevatorSDKServerCloudServiceClient.getElevatorInfoForRobot(cloudElevatorSDKGetByDeviceUniqueDTO);

        Map<String, Object> signMap = new HashMap<>();
        signMap.put("data", JSON.toJSONString(cloudElevatorSDKGetByDeviceUniqueVOS));
        LOG.info("======getElevatorInfo根据设备唯一码查询电梯信息======无感======出参================>{}",signMap.toString());
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(signMap,dto.getRequestId(),dto.getResponseTimestamp(), dto.getAppSecret()), cloudElevatorSDKGetByDeviceUniqueVOS);
    }

    /**
     * <desc>
     * 预约电梯
     * <desc/>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2019-01-03
     */
    @RequestMapping(value = "/callElevator", method = RequestMethod.POST)
    @LoggerInfo(operateDesc = LogDescConstant.SDK_ROBOT_CALL_ELEVATOR)
    @ResponseBody
    public Object callElevator() {
        //收到请求的时间
        long requestTime = (new Date()).getTime();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudDeviceSDKDTO cloudElevatorSDKCallElevatorDTO =
                    HttpProtocolUtil.parseRequestParamToDTO(CloudDeviceSDKDTO.class, request);
            cloudElevatorSDKCallElevatorDTO.setAppId(request.getAttribute("appId").toString());
            cloudElevatorSDKCallElevatorDTO.setAppSecret(request.getAttribute("appSecret").toString());
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", cloudElevatorSDKCallElevatorDTO.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_ELEVATOR_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime()+"";
            LOG.info("======callElevator预约电梯机器人无感============入参================>{}",cloudElevatorSDKCallElevatorDTO.toString());

            //初始值为 登录为工程人员登录  获取项目下所有的设备
            Integer robotWhiteListAuthStatus=0;
            Integer robotDeviceAuthStatus=0;
            if (!"1".equals(cloudElevatorSDKCallElevatorDTO.getRoleId())) {
                Map<String, Object> AuthStatus = iOperateProjectServiceClient.getRobotGoProjectWhitelistAndDeviceAuthStatusByUserId(cloudElevatorSDKCallElevatorDTO.getProjectId(), cloudElevatorSDKCallElevatorDTO.getAppId());
                robotWhiteListAuthStatus = Integer.parseInt(AuthStatus.get("robotWhiteListAuthStatus") + "");
                robotDeviceAuthStatus = Integer.parseInt(AuthStatus.get("robotDeviceAuthStatus") + "");
            }
            cloudElevatorSDKCallElevatorDTO.setRobotWhiteListAuthStatus(robotWhiteListAuthStatus);
            cloudElevatorSDKCallElevatorDTO.setRobotDeviceAuthStatus(robotDeviceAuthStatus);

            if ("1".equals(robotWhiteListAuthStatus+"")) {
                if (StringUtils.isBlank(cloudElevatorSDKCallElevatorDTO.getProjectId()) || StringUtils.isBlank(cloudElevatorSDKCallElevatorDTO.getRobotId())) {
                    return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), cloudElevatorSDKCallElevatorDTO.getRequestId(), responseTimestamp, "");
                }
            }
            String deviceUnique = iCloudElevatorSDKServerCloudServiceClient.getDeviceUniqueByControllerDeviceUnique(cloudElevatorSDKCallElevatorDTO.getControllerDeviceUnique());
            if (StringUtils.isBlank(deviceUnique)) {
                return new SDKMessageVO(CloudElevarotErrorCodeEnum.CONTROLLER_NOT_FOUND.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
            }
            cloudElevatorSDKCallElevatorDTO.setDeviceUnique(deviceUnique);
            cloudElevatorSDKCallElevatorDTO.setRobotDevelopDeviceType(1);
            cloudElevatorSDKCallElevatorDTO.setDeviceType("4");
            cloudElevatorSDKCallElevatorDTO.setRobotId(robotWhiteListAuthStatus==0?"":cloudElevatorSDKCallElevatorDTO.getRobotId());
            //设备权限以及机器人权限验证
            int result = sdkCloudElevatorRTLController.checkDeveloperAuth(cloudElevatorSDKCallElevatorDTO);
            if (result == 1) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_SERVER_NO_DEVICE_UNIQUE_ERR.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
            } else if (result == 2) {
                return new SDKMessageVO(CloudElevarotErrorCodeEnum.ROBOT_AUTH_ERROR.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
            }
            deviceUnique = StringHandlerUtil.splitString(deviceUnique)[0];

            //云电梯设备判断,标准版不支持机器人呼梯
            DeviceElevatorInfoPO po = iCloudElevatorSDKServerCloudServiceClient.getElevatorByDeviceUnique(cloudElevatorSDKCallElevatorDTO.getDeviceUnique());
            if (po != null && po.getDeviceAttributes() != null && po.getDeviceAttributes() == 1) {//设备属性配置 ：1标准 2云机器人 3全功能
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_DEVICE_NOT_SUPPORT_THIS_FUNCTIONS.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
            }

            //查询电梯设备是否绑定控制器
            Map<String, Object> controller = iAppDeviceServiceClient.getControllerDeviceUniqueByElevatorDeviceUnique(deviceUnique);
            String isOnline;
            //判断群控器是否在线
            if (controller != null && controller.get("groupConId") != null) {
                isOnline = iIotServerServiceClient.batchGetDeviceState(controller.get("iotProductKey").toString(), controller.get("groupConId").toString());
                if (isOnline == null || (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType()))) {
                    return new SDKMessageVO(AppErrorCodeEnum.CLOUD_ELEVATOR_OUT_LINE.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
                }
            }
            if ("1".equals(robotWhiteListAuthStatus+"")) {
                //判断当前机器人之前预约行程是否完成
                Integer operateStatus = iCloudElevatorSDKRobotServiceClient.checkSuccessState(cloudElevatorSDKCallElevatorDTO.getRobotId(), cloudElevatorSDKCallElevatorDTO.getControllerDeviceUnique());
                if (operateStatus != null && operateStatus != 2) {//有行程,10秒之内不是完成状态不允许再次呼梯
                    return new SDKMessageVO(SDKErrorCodeEnum.SDK_ROBOT_CALL_ELEVATOR_RECORD_ERR.getErrorCode(), cloudElevatorSDKCallElevatorDTO.getRequestId(), responseTimestamp, "");
                }

            //删除呼梯结果缓存
            redisService.delForDevice(RedisConstant.REDIS_IOT_CLOUD_CONTROLLER_NOTIFY_MESSAGE_CACHE +
                    cloudElevatorSDKCallElevatorDTO.getControllerDeviceUnique() + cloudElevatorSDKCallElevatorDTO.getRobotId());
            }
            //获取真实楼层
            Map<String, Object> floor = iCloudElevatorSDKServerCloudServiceClient.getFloorNumByLogicFloor(cloudElevatorSDKCallElevatorDTO.getToFloor(), cloudElevatorSDKCallElevatorDTO.getFromFloor(),
                    deviceUnique);
            if (floor == null || floor.get("goFloor") == null || floor.get("fromFloor") == null) {
                return new SDKMessageVO(CloudElevarotErrorCodeEnum.CLOUD_FLOOR_ERROR.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,"");
            }
            //调用IOT呼梯
            String snr = LogicIdUtil.bussinessId();
            LOG.info("【呼梯日志 requestId requestTime snr】{} {} {}", cloudElevatorSDKCallElevatorDTO.getRequestId(), requestTime, snr);
            iAppDeviceServiceClient.cloudElevatorCall(deviceUnique,
                    CloudElevatorSourceEnum.ITLONG_CLOUD_ELEVATOR.getDescription(),
                    floor.get("fromFloor").toString(), floor.get("goFloor").toString(), null,
                    CloudElevatorCallTypeEnum.OUT.getType(), null, CallElevatorSourceTypeEnum.ROBOT.getType(), cloudElevatorSDKCallElevatorDTO.getRobotId(), snr, null, 1, cloudElevatorSDKCallElevatorDTO.getUpDown(), null, cloudElevatorSDKCallElevatorDTO.getRequestId());
            //装配呼梯记录对象
            AppCallLiftSaveDTO saveDTO = new AppCallLiftSaveDTO();
            saveDTO.setDeviceUnique(cloudElevatorSDKCallElevatorDTO.getControllerDeviceUnique());
            saveDTO.setFromFloor(floor.get("fromNaturalFloor").toString());
            saveDTO.setToFloor(floor.get("goNaturalFloor").toString());
            saveDTO.setProjectId(cloudElevatorSDKCallElevatorDTO.getProjectId());
            saveDTO.setUserId(robotWhiteListAuthStatus==0?cloudElevatorSDKCallElevatorDTO.getAppId():cloudElevatorSDKCallElevatorDTO.getRobotId());
            saveDTO.setSource(CallElevatorRecordSourceEnum.ROBOT.getType());
            iAppHomeServiceClient.saveCallLiftRecord(saveDTO);
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),cloudElevatorSDKCallElevatorDTO.getRequestId(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(),cloudElevatorSDKCallElevatorDTO.getRequestId(),responseTimestamp,
                            cloudElevatorSDKCallElevatorDTO.getAppSecret()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_机器人无感通行_callElevator】预约电梯异常", e);
        }
    }

    /**
     * <desc>
     * 获取群控器呼梯结果信息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2019/07/17
     */
    @ResponseBody
    @PostMapping("/getCallInfo")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_GET_CONTROLLER_NOTIFY_MESSAGE_DESC)
    public Object getCallInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            RobotNoninductiveGetCallInfoVO robotNoninductiveGetCallInfoVO = HttpProtocolUtil.parseRequestParamToDTO(RobotNoninductiveGetCallInfoVO.class, request);
            robotNoninductiveGetCallInfoVO.setAppSecret(request.getAttribute("appSecret").toString());
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", robotNoninductiveGetCallInfoVO.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_ELEVATOR_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime()+"";
            LOG.info("======getCallInfo获取群控器呼梯结果信息无感============入参================>{}",robotNoninductiveGetCallInfoVO.toString());
            if (StringUtils.isBlank(robotNoninductiveGetCallInfoVO.getControllerDeviceUnique())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(),request.getAttribute("requestId").toString(),responseTimestamp,"");
            }
            String deviceUnique = iCloudElevatorSDKServerCloudServiceClient.getCallInfo(robotNoninductiveGetCallInfoVO.getRobotId(), robotNoninductiveGetCallInfoVO.getControllerDeviceUnique());
            Map<String, Object> data = new HashMap<>();
            data.put("deviceUnique", deviceUnique);
            Map<String, Object> signMap = new HashMap<>();
            signMap.put("data",new JSONObject(data));//签名使用json格式内容进行
            LOG.info("======getCallInfo获取群控器呼梯结果信息无感============出参================>{}",signMap.toString());

            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(signMap,request.getAttribute("requestId").toString(),responseTimestamp, robotNoninductiveGetCallInfoVO.getAppSecret()), data);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_机器人无感通行_getCallInfo】获取群控器呼梯结果信息失败", e);
        }
    }

    /**
     * <desc>
     * 获取群控器呼梯记录
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2019/07/17
     */
    @ResponseBody
    @PostMapping("/historyCallRecord")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_GET_CONTROLLER_NOTIFY_MESSAGE_DESC)
    public Object historyCallRecord() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            RobotNoninductiveHistoryRecordDTO recordDTO = HttpProtocolUtil.parseRequestParamToDTO(RobotNoninductiveHistoryRecordDTO.class, request);
            recordDTO.setAppId(request.getAttribute("appId").toString());
            recordDTO.setAppSecret(request.getAttribute("appSecret").toString());
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", recordDTO.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_ELEVATOR_TYPE_LOG_DESC);
            Page<RobotNoninductiveHistoryRecordVO> page = iCloudElevatorSDKServerCloudServiceClient.getHistoryRecords(recordDTO);
            //保存生成操作日志所需信息 详细描述和接口类别
            String responseTimestamp = new Date().getTime()+"";
            //此接口不用返回值签名
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(),request.getAttribute("requestId").toString(),responseTimestamp, recordDTO.getAppSecret()), page);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_机器人无感通行_historyCallRecord】获取群控器呼梯记录失败", e);
        }
    }
}
